import sys,os
import logging
import numpy as np
import colorsys

#Current path
cur_path = os.path.dirname(os.path.realpath( os.path.basename(__file__)))

#Logging
logger = logging.getLogger("EFE")
logger.setLevel(logging.DEBUG)
logger.propagate = False

ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

formatter = logging.Formatter('%(asctime)s\t(%(name)s)\t[%(levelname)s]\t%(message)s')

ch.setFormatter(formatter)

logger.addHandler(ch)


#Plotting colors generation
def _get_colors(num_colors):
	colors=[]
	for i in np.arange(0., 360., 360. / num_colors):
		hue = i/360.
		lightness = (50 + np.random.rand() * 10)/100.
		saturation = (90 + np.random.rand() * 10)/100.
		colors.append(colorsys.hls_to_rgb(hue, lightness, saturation))
	return colors

#colors = ['g','c','r','b','m','k','y',"orange",'indigo','salmon','crimson','hotpink','saddlebrown','lightgreen','yellowgreen','peru','gray','darkred']
colors = _get_colors(25)


#Normal random tensor generation
def randn(*args): return np.random.randn(*args).astype('f')


#Projection onto the L2 sphere (TransE embeddings)
def L2_proj(M):
	"""
	Projection on L2 sphere row-wise
	"""
	norm_M = np.linalg.norm(M,axis=1)
	M /=  norm_M[:,None]
	return M


#Tool classes:

class Parameters(object):

	def __init__(self, lmbda = 0.1, embedding_size = 100, batch_size =100, max_iter = 1000, learning_rate = 0.1, neg_ratio = 0, contiguous_sampling = False,
			valid_scores_every = 50, learning_rate_policy = 'adagrad'):

		self.lmbda = lmbda 								# L2 Regularization param
		self.embedding_size = embedding_size 			# Size of the embeddings (in NTN and factorization based models)
		self.batch_size = batch_size 					# Size of the minibatches for optimization
		self.max_iter = max_iter 						# Maximum number of iterations over the data
		self.learning_rate = learning_rate 				# Learning rate for gradient based methods
		self.neg_ratio = neg_ratio						# Number of negative triples generated by positive
		self.contiguous_sampling = contiguous_sampling	# Continous or random sampling among train samples
		self.valid_scores_every = valid_scores_every	# Compute validation scores every this number of iteration for early stopping
		self.learning_rate_policy = learning_rate_policy# Learning rate policy, see downhill documentation

class Triplets_set(object):
	"""
	self.indexes attribute is a n*3 numpy array that are all triplets in the set,
	with their corresponding values (1 or -1) in self.values
	"""

	def __init__(self, indexes, values):

		#Type cast to comply with theano types defined in downhill losses
		self.indexes = indexes.astype(np.int64)
		self.values = values.astype(np.float32)



